package com.flyme.module.base.provider.api;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.egzosn.pay.common.bean.PayOrder;
import com.flyme.common.core.aliyun.sms.AliSmsUtil;
import com.flyme.common.core.aliyun.sms.SmsTempEnum;
import com.flyme.common.core.constants.CommonConstants;
import com.flyme.common.core.model.ResultBody;
import com.flyme.common.core.model.query.CriteriaQuery;
import com.flyme.common.core.model.query.PagerInfo;
import com.flyme.common.core.model.query.PqGrid;
import com.flyme.common.core.security.OpenHelper;
import com.flyme.common.core.security.OpenUserAuth;
import com.flyme.common.core.utils.*;
import com.flyme.core.base.supper.controller.BaseController;
import com.flyme.core.base.supper.entity.EntityMap;
import com.flyme.core.base.utils.RedisUtils;
import com.flyme.module.base.client.api.SysRegRemoteService;
import com.flyme.module.base.client.dto.SysThirdLogin;
import com.flyme.module.base.client.entity.*;
import com.flyme.module.base.client.enums.SortEnum;
import com.flyme.module.base.client.enums.StatusEnum;
import com.flyme.module.base.provider.rong.RcUtils;
import com.flyme.module.base.provider.rong.models.TokenResult;
import com.flyme.module.base.provider.service.*;
import com.flyme.module.base.provider.service.impl.SysBalanceServiceImpl;
import com.flyme.module.exam.provider.service.BusUserabilityService;
import com.flyme.module.exam.provider.service.ExamRecordService;
import com.flyme.module.file.client.entity.SysCataLog;
import com.flyme.module.file.client.entity.SysCourse;
import com.flyme.module.file.client.entity.SysCourseType;
import com.flyme.module.file.client.entity.SysLive;
import com.flyme.module.file.provider.service.*;
import com.flyme.module.order.client.entity.Order;
import com.flyme.module.order.client.entity.PayAccount;
import com.flyme.module.order.client.enums.OrderTypeEnum;
import com.flyme.module.order.client.enums.PayTypeEnum;
import com.flyme.module.order.client.vo.PayType;
import com.flyme.module.order.provider.service.OrderService;
import com.flyme.module.order.provider.service.PayAccountService;
import com.flyme.module.order.provider.service.PayResponse;
import com.flyme.module.order.provider.unionpay.XmlUtileXM;
import com.flyme.module.order.provider.unionpay.ZSHttpRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 不需要登录鉴权额接口管理
 *
 * @author flyme
 */
@Slf4j
@Api(tags = "无需鉴权接口")
@RestController
@RequestMapping("/common")
public class ApiLoginController extends BaseController<SysUserService, SysUser> {

    @Autowired
    private PayAccountService service;
    @Autowired
    private OrderService orderService;
    @Autowired
    private SysAccountService accountService;
    @Autowired
    private SysCourseTypeService courseTypeService;
    @Autowired
    private SysUserService userService;
    @Autowired
    private SysRegRemoteService regRemoteService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SysVersionService versionService;
    @Autowired
    private SysSliderService sliderService;
    @Autowired
    private SysCourseEnrollService courseEnrollService;
    @Autowired
    private SysLiveService liveService;
    @Autowired
    private SysOffCourseService offCourseService;
    @Autowired
    private SysLecturerService lecturerService;
    @Autowired
    private SysIndextagService indextagService;
    @Autowired
    private SysCourseService courseService;
    @Autowired
    private SysColleconService colleconService;
    @Autowired
    private SysFictionService fictionService;
    @Autowired
    private SysKeywordService keywordService;
    @Autowired
    private SysConfigService configservice;
    @Autowired
    private SysCataLogService catalogService;
    @Autowired
    private SysCourseEnrollService courseapplyService;
    @Autowired
    private SysHistoryService historyService;
    @Autowired
    private SysBalanceService balanceService;
    @Autowired
    private BusUserabilityService userabilityService;
    @Autowired
    private SysCourseCommentService commentService;
    @Autowired
    private SysVipTypeService vipTypeService;
    @Autowired
    private SysVipconfigService vipconfigService;
    @Autowired
    private SysVipService vipService;
    @Autowired
    private SysCourseCommentService courseCommentService;
    @Autowired
    private SysHtmlService htmlService;
    @Autowired
    private SysVipPriceService vipPriceService;
    @Autowired
    private ExamRecordService examRecordService;
    @Autowired
    private SysUserexaminationService sysUserexaminationService;
    @Autowired
    private SysBalanceServiceImpl paybackService;
    @Autowired
    private SysUsercertificateService sysUsercertificateService;
    @Autowired
    private SysCertifistudyrecordService sysCertifistudyrecordService;
    @Autowired
    private SysCataLogService sysCataLogService;
    @Autowired
    private SysContinuecourseService sysContinuecourseService;
    @Autowired
    private SysPeriodrecordService sysPeriodrecordService;
    @Autowired
    private SysStudyconfigService sysStudyconfigService;
    @Autowired
    private SysActivityrecordService sysActivityrecordService;

    /**
     * 验证验证码
     */
    @RequestMapping(value = "/yanzheng")
    public ResultBody yanzheng(String mobile, String smsCode) {
        ApiAssert.notNull("内容不能为空", smsCode, mobile);
        if (ObjectUtils.isNotEmpty(smsCode)) {
            String v = redisUtils.getString(CommonConstants.PRE_SMS + mobile);
            ApiAssert.notNull("验证码无效", v);
            ApiAssert.eq("验证码不正确", smsCode, v);
        }
        return ResultBody.ok("验证成功");
    }
    @ApiOperation(
        value = "微信支付成功回调成功回调"
    )
    @RequestMapping({"/pay_succ"})
    public String paySucc(HttpServletRequest request) {
//        PayResponse payResponse = service.getPayResponse(request);
        try {
            CriteriaQuery qw=new CriteriaQuery();
            qw.select("partner,appId,publicKey,privateKey,notifyUrl,returnUrl,seller,signType,inputCharset,isTest");
            qw.eq("id","2");
            PayAccount a=service.getOne(qw);
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            Map<String, String> result = xmlToMap(xmlResult);
            String return_code = result.get("return_code");
            String outTradeNo = result.get("out_trade_no");
            if ("SUCCESS".equals(return_code)) {
                String respSign = result.get("sign");
                if (!respSign.equals(getWechatSign(result,  a.getPrivateKey()))) {
                    log.error("验签失败==============");
                    return "fail";
                }
//                boolean order_1=orderService.updateWxOrder(outTradeNo);
                Order order=orderService.findByNo(outTradeNo);
                log.error("===================================================小程序订单查询"+order.getId()+"订单编号"+outTradeNo);
                order.setPayType(PayTypeEnum.WechatPay);//微信小程序支付
                ResultBody order_2=paybackService.pay_back(order);
                return "SUCCESS";
            }
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因{}", e.getMessage());
            return "fail";
        }
        return "fail";
    }
    /**
     * XML转MAP
     *
     * @param strXML
     * @return
     * @throws Exception
     */
    private Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return data;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
    /**
     * 获取微信支付签名
     *
     * @param map
     * @return
     * @throws Exception
     */
    private String getWechatSign(Map<String, String> map, String key) throws Exception {
        Set<String> keySet = map.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if ("sign".equals(k)) {
                continue;
            }
            // 参数值为空，则不参与签名
            if (map.get(k).trim().length() > 0) {
                sb.append(k).append("=").append(map.get(k).trim()).append("&");
            }
        }
        sb.append("key=").append(key);
        return MD5(sb.toString()).toUpperCase();
    }

    /**
     * MD5加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    private String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }


    /**
     * 登录成功初始化
     */
    @RequestMapping(value = "/init_login")
    public ResultBody initLogin() {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        SysUser user = userService.getById(openUserAuth.getUserId());
        SysBalance balance = balanceService.findByUser(openUserAuth.getUserId());
        if (ObjectUtils.isEmpty(balance)) {
            balanceService.insert(openUserAuth.getUserId());
        }
        Integer num = userabilityService.countByUser(openUserAuth.getUserId());
        if (num < 1) {
            //初始化段位等级
            userabilityService.initUserability(openUserAuth.getUserId());
        }
        String rongToken = initRongToken(user);
        Map map = openUserAuth.getUserProfile();
        map.put("avatar", user.getAvatar());
        map.put("rongToken", rongToken);
        return ResultBody.success(map);
    }

    /**
     * 设置融云token
     */
    public String initRongToken(SysUser user) {
        String rongToken = user.getRongToken();
        if (ObjectUtils.isEmpty(rongToken)) {
            TokenResult tokenResult = RcUtils.getToken(user);
            rongToken = tokenResult.getToken();
            userService.updateRong(user.getId(), rongToken);
        }
        return rongToken;
    }

    /**
     * 第三方登录(初始化登录账户)
     */
    @RequestMapping(value = "/third_login")
    public ResultBody thirdLogin(SysThirdLogin thirdLogin) {
        EntityMap map = new EntityMap();
        //初始化登录账户
        SystemAccount account = accountService.registerByThird(thirdLogin);
        Long userId = account.getUserId();
        //用户绑定状态
        Integer bindStatus;
        if (ObjectUtils.isNotEmpty(userId)) {
            //绑定状态依据是否创建用户信息
            bindStatus = CommonConstants.ENABLED;
        } else {
            bindStatus = CommonConstants.DISABLED;
        }
        String username = account.getAccount();
        String password = CommonConstants.DEF_PWD;
        map.put("username", username);
        map.put("password", password);
        map.put("accountId", account.getId());
        map.put("bindStatus", bindStatus);
        return ResultBody.success(map);
    }

    /**
     * 第三方登录(绑定手机号)
     */
    @RequestMapping(value = "/bind_mobile")
    public ResultBody bind_mobile(String accountId, String mobile, String smsCode) {
        ApiAssert.notNull("验证码不能为空", smsCode, mobile);
        if (ObjectUtils.isNotEmpty(smsCode)) {
            String v = redisUtils.getString(CommonConstants.PRE_SMS + mobile);
            ApiAssert.notNull("验证码无效", v);
            ApiAssert.eq("验证码不正确", smsCode, v);
        }
        //默认注册为学员用户
        Boolean tag = accountService.bingMobile("UT_STUDENT", accountId, mobile);
        return ResultBody.ok("綁定成功").success(tag);
    }

    /**
     * 获取验证码登录并注册账户
     */
    @RequestMapping(value = "/sendSms", method = RequestMethod.GET)
    @ApiOperation(value = "发送短信验证码")
    public ResultBody sendSms(@RequestParam String mobile, String time,Long invitedId,String inviteType) {
        ApiAssert.notNull("参数不能为空", mobile, time);
        mobile = DesUtils.getTel(mobile, time);
        // 发送限流 1分钟限1个请求
        // String tokenLimit = redisRaterLimiter.acquireTokenFromBucket("sendSms:" + mobile, 1, 60000);
        //ApiAssert.notNull("您发送的太频繁啦，请稍后再试", tokenLimit);

        String regex = "^[1][3,4,5,6,7,8][0-9]{9}$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(mobile);
        boolean isMatch = m.matches();
        if(!isMatch){
            return ResultBody.failed("手机号不合法");
        }
        SystemAccount account = accountService.findByAccount(mobile);
        if (ObjectUtils.isEmpty(account)) {
            regRemoteService.regByMobile(mobile, "UT_STUDENT",invitedId);
        }else{
            SysUser user= userService.findByMobile(mobile);
            if(ObjectUtils.isNotEmpty(user)&&ObjectUtils.isNotEmpty(inviteType)&&ObjectUtils.isNotEmpty(invitedId)){
            if(inviteType.equals("1")){//考试推荐类型
                user.setExaminvitedId(invitedId);
            }
            if(inviteType.equals("2")){//会员购买类型
                user.setVipinvitedId(invitedId);
            }
            if(inviteType.equals("3")){//课程购买类型
                user.setCourseinvitedId(invitedId);
            }
            }
            userService.saveOrUpdate(user);
        }

        // 生成6位数验证码
        String code = new CreateVerifyCode().getRandomNum();
        // 缓存验证码
        redisUtils.set(CommonConstants.PRE_SMS + mobile, code, 900);
        //发送验证码
        Map<String, String> params = new HashMap<>();
        params.put("code", code);
        Boolean tag = AliSmsUtil.sendSmsCode(SmsTempEnum.REG, mobile, params);
        return ResultBody.ok("发送成功").success(code);
    }

    /**
     * 发送验证码（换绑手机号时，不对新手机号进行注册操作）
     */
    @RequestMapping(value = "/sendSms2")
    @ApiOperation(value = "发送短信验证码")
    public ResultBody sendSms2(@RequestParam String mobile, String time) {
        ApiAssert.notNull("参数不能为空", mobile, time);
        mobile = DesUtils.getTel(mobile, time);
        ApiAssert.notNull("非法请求", mobile);
        // 发送限流 1分钟限1个请求
        // String tokenLimit = redisRaterLimiter.acquireTokenFromBucket("sendSms:" + mobile, 1, 60000);
        // ApiAssert.notNull("您发送的太频繁啦，请稍后再试", tokenLimit);
        String regex = "^[1][3,4,5,6,7,8][0-9]{9}$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(mobile);
        boolean isMatch = m.matches();
        if(!isMatch){
            return ResultBody.failed("手机号不合法");
        }
        // 生成6位数验证码
        String code = new CreateVerifyCode().getRandomNum();
        // 缓存验证码
        redisUtils.set(CommonConstants.PRE_SMS + mobile, code, 900);
        //发送验证码
        Map<String, String> params = new HashMap<>();
        params.put("code", code);
        Boolean tag = AliSmsUtil.sendSmsCode(SmsTempEnum.REG, mobile, params);
        return ResultBody.ok("发送成功").success(code);
    }

    /**
     * 发送验证码（换绑手机号时，不对新手机号进行注册操作）
     */
    @RequestMapping(value = "/sendSmsByWeb")
    @ApiOperation(value = "发送短信验证码")
    public ResultBody sendSmsByWeb(@RequestParam String mobile) {
        ApiAssert.notNull("参数不能为空", mobile);
        mobile = AesEncryptUtil.desEncrypt(mobile);
        ApiAssert.notNull("非法请求", mobile);
        // 发送限流 1分钟限1个请求
        // String tokenLimit = redisRaterLimiter.acquireTokenFromBucket("sendSms:" + mobile, 1, 60000);
        // ApiAssert.notNull("您发送的太频繁啦，请稍后再试", tokenLimit);
        String regex = "^[1][3,4,5,6,7,8][0-9]{9}$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(mobile);
        boolean isMatch = m.matches();
        if(!isMatch){
            return ResultBody.failed("手机号不合法");
        }
        // 生成6位数验证码
        String code = new CreateVerifyCode().getRandomNum();
        // 缓存验证码
        redisUtils.set(CommonConstants.PRE_SMS + mobile, code, 900);
        //发送验证码
        Map<String, String> params = new HashMap<>();
        params.put("code", code);
        Boolean tag = AliSmsUtil.sendSmsCode(SmsTempEnum.REG, mobile, params);
        return ResultBody.ok("发送成功").success(code);
    }

    /**
     * 首页
     */
    @RequestMapping(value = "/index")
    public ResultBody index(HttpServletResponse response, PagerInfo pagerInfo) {
        //OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        EntityMap map = new EntityMap();
        List<SysSlider> sliders = sliderService.selectSliders(1, 1);// 轮播图
        List<EntityMap> lives = liveService.selectLive(1);// 在线直播
        for (EntityMap live : lives) {
            //live.put("liveTime", DateTime.getDateTime(live.get("liveTime"), DateUtil.MM月dd日HHmm));
        }
        List<EntityMap> fictions = fictionService.selectFictions();
        List<EntityMap> courses = offCourseService.selectLiveCourse();// 线下课程
        List<EntityMap> lecturers = lecturerService.selectLecturers(pagerInfo);// 为你推荐-讲师
        List<Map<String, Object>> indextags = indextagService.selectShow();
        if (indextags.size() > 0) {
            for (Map<String, Object> it : indextags) {
                List<EntityMap> indexShow = courseService.selectInderCourse(pagerInfo, it.get("id").toString());// 为你推荐
                it.put("indexShow", indexShow);
            }
        }
        /*if (ObjectUtils.isNotEmpty(openUserAuth)) {
            String accountId = String.valueOf(openUserAuth.getUserId());
            usermessageService.initMsg(accountId);
        }*/
        map.put("recommendList", indextags);
        map.put("sliders", sliders);
        map.put("lives", lives);
        map.put("fictions", fictions);
        map.put("courses", courses);
        map.put("lecturers", lecturers);
        return ResultBody.success(map);
    }

    /**
     * 中物协首页
     */
    @RequestMapping(value = "/third_index_zwx")
    public ResultBody third_index_zwx(HttpServletResponse response, PagerInfo pagerInfo) {
        EntityMap map = new EntityMap();
        List<SysSlider> sliders = sliderService.selectSliders(1, 1);// 轮播图
        List<EntityMap> courses = courseService.selectInderCourse(pagerInfo, "");// 为你推荐
        map.put("sliders", sliders);
        map.put("courses", courses);
        return ResultBody.success(map);
    }

    /**
     * 首页
     */
    @RequestMapping(value = "/third_index")
    public ResultBody third_index(HttpServletResponse response, PagerInfo pagerInfo) {
        //OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        EntityMap map = new EntityMap();
        List<SysSlider> sliders = sliderService.selectSliders(1, 1);// 轮播图
        List<EntityMap> lives = liveService.selectLive(1);// 在线直播
        for (EntityMap live : lives) {
            //live.put("liveTime", DateTime.getDateTime(live.get("liveTime"), DateUtil.MM月dd日HHmm));
        }
        List<EntityMap> courses = offCourseService.selectLiveCourse();// 线下课程
        map.put("sliders", sliders);
        map.put("lives", lives);
        map.put("courses", courses);
        return ResultBody.success(map);
    }

    /**
     * 获取最新版本 -用户
     */
    @RequestMapping(value = "/version")
    public ResultBody getversion(String verCode) {
        if (ObjectUtils.isEmpty(verCode)) {
            verCode = "android";
        }
        EntityMap map = new EntityMap();
        SysVersion version = versionService.getVersion(verCode);
        map.put("verName", version.getVerName());
        map.put("versionId", version.getId());
        map.put("verNo", version.getVerNo());
        map.put("verTitle", version.getVerTitle());
        map.put("verContent", version.getVerContent());
        map.put("verUrl", version.getVerUrl());
        map.put("forceUpdate", version.getForceUpdate());
        map.put("createDate", version.getCreateTime());
        return ResultBody.success(map);
    }


    /**
     * 试听课（小程序）
     */
    @PostMapping(value = "/auditionCourse")
    public ResultBody auditionCourse(PagerInfo pagerInfo) {
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        cq.addSql("c.id,c.courseTitle,c.recordNum,c.courseImage");
        cq.eq("isContinue", 2);
        cq.eq("courseStatus", 1);
        PqGrid pqGrid = courseService.pageList(cq);
        return ResultBody.success(pqGrid);
    }

    /**
     * 课程列表
     */
    @RequestMapping(value = "/course_list")
    public ResultBody orderList(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo, String coursetypeId, String sortOT, String status) {
        EntityMap map = new EntityMap();
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        List<String> list = courseTypeService.selectTypeByType(coursetypeId);
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        cq.addSql("c.id,c.courseTitle,c.recordNum,c.courseImage,c.lecturerId,c.coursePrice,user.userName,user.avatar,c.isVipFree,c.isFree,c.onLine");
        cq.addSql("(select count(id) from sys_catalog ca where ca.courseId=c.id and parentId!=0) courseCount");
        cq.addSql("(round(c.coursePrice*" + iosRatio + ")) iosPrice");
        if (list.size() > 1) {//一级目录
            cq.in("courseTypeId", list);
        } else {
            cq.eq("courseTypeId", coursetypeId);
        }
        cq.eq("isContinue", 0);
        cq.eq("courseStatus", 1);
        cq.createAlias("user", "user");
        //状态
        if (ObjectUtils.isNotEmpty(status)) {
            //免费
            if ("S_01".equals(status)) {
                cq.eq("isFree", 0);
            }
            //vip免费
            if ("S_02".equals(status)) {
                cq.eq("isVipFree", 0);
                cq.eq("isFree", 1);
                cq.gt("coursePrice", 0);
            }
            //不是vip免费且金额大于0
            if (status.equals("S_03")) {
                cq.gt("coursePrice", 0);
                cq.eq("isVipFree", 1);
            }
        }
        if (ObjectUtils.isNotEmpty(sortOT)) {//排序
            if (sortOT.equals("SORT_01")) {//最新
                cq.orderByDesc("c.createTime");
            }
            if (sortOT.equals("SORT_02")) {//价格升序
                cq.orderByAsc("coursePrice");
            }
            if (sortOT.equals("SORT_03")) {//价格降序
                cq.orderByDesc("coursePrice");
            }
        } else {
            cq.orderByAsc("c.sortOrder");
        }
        PqGrid pqGrid = courseService.pageList(cq);
        List<EntityMap> sortList = SortEnum.getList();
        List<EntityMap> statusList = StatusEnum.getList();
        List<EntityMap> lists = (List<EntityMap>) pqGrid.getRows();
        map.put("isVip", 0);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Integer vip = vipService.isVip(openUserAuth.getUserId());
            map.put("isVip", vip);
        }
        map.put("sortList", sortList);//排序类型
        map.put("statusList", statusList);//状态类型
        map.put("lists", lists);
        return ResultBody.success(map);
    }

    /**
     * 线下课程详情
     */
    @RequestMapping(value = "/offCourse_detail")
    public ResultBody offlineCourseDetail(Long courseId) {
        ApiAssert.notNull("参数不能为空", courseId);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        EntityMap map = offCourseService.getEntityMap(q().eq("id", courseId));
        Date deadline = map.get("deadline");
        Integer applyNum = courseEnrollService.applyNum(courseId,3);
        map.put("isApply", 0);//用户是否已经报名（0未报名1已报名）
        map.put("userId", "");
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Long userId = openUserAuth.getUserId();
            Integer isApply = courseEnrollService.isApply(courseId, userId, 3);
            map.put("isApply", isApply);//用户是否已经报名（0未报名1已报名）
            map.put("userId", userId);
        }
        String lecturerId = map.get("lecturerId");
        if (ObjectUtils.isNotEmpty(lecturerId)) {
            SysUser lecturer = userService.getById(lecturerId);
            map.put("lecturerName", lecturer.getUserName());//导师姓名
            map.put("lecturerImg", lecturer.getAvatar());//导师图片
        } else {
            map.put("lecturerName", "");//导师姓名
            map.put("lecturerImg", "");//导师图片
        }
        map.put("courseId", courseId);
        if (ObjectUtils.isEmpty(map.get("enrollNum"))) {
            map.put("enrollNum", 0);
        }
        map.put("applyNum", applyNum);//已报名人数
        Integer applyType = map.get("applyType");
        if (DateUtil.date().after(deadline)) {
            applyType = 0;
        }
        map.put("applyType", applyType);//是否截至
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        BigDecimal price = new BigDecimal(map.get("coursePrice").toString());
        map.put("iosPrice", price.multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
        return ResultBody.success(map);
    }


    /**
     * 线下课程列表
     */
    @RequestMapping(value = "/offCourse_list")
    public ResultBody offlineCoursePage(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo) {
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        cq.select("id,courseTitle,courseImage,coursePrice,(select count(*) from sys_courseenroll ce where ce.targetId=oc.id) recordNum,user.avatar");
        cq.eq("courseStatus", 1);
        cq.createAlias("user", "user");
        PqGrid pqGrid = offCourseService.pageList(cq);
        return ResultBody.success(pqGrid);
    }

    /**
     * 课程分类
     */
    @RequestMapping(value = "/coursetype_list")
    public ResultBody allCoursePage() {
        List<SysCourseType> list = courseTypeService.selectByParentId(0L);
        for (SysCourseType courseType : list) {
            List<SysCourseType> child = courseTypeService.selectByParentId(courseType.getId());
            courseType.setChild(child);
        }
        return ResultBody.success(list);
    }

    /**
     * 直播列表
     * isVip:0不是1企业2个人3既是企业又是个人
     */
    @RequestMapping(value = "/live_list")
    public ResultBody liveList(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo, SysLive live) {
        EntityMap map = new EntityMap();
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        cq.select("id,liveTitle,liveImage,liveTime,channelId,isVipFree");
        cq.eq("liveStatus", CommonConstants.ENABLED);
        cq.orderByAsc("sortOrder");
        PqGrid pqGrid = liveService.pageList(cq);
        map.put("isVip", 0);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Integer vip = vipService.isVip(openUserAuth.getUserId());
            map.put("isVip", vip);
        }
        map.put("list", pqGrid);
        return ResultBody.success(map);
    }

    /**
     * 直播详情
     */
    @RequestMapping(value = "/live_details")
    public ResultBody liveDetails(String liveId) {
        ApiAssert.notNull("参数不能为空", liveId);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        EntityMap map = new EntityMap();
        SysLive live = liveService.getById(liveId);
        // 用户是否已经报名（0未报名1已报名）
        Integer isApply = 0;
        Integer isCollecon = 0;
        String url = "";
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Long userId = openUserAuth.getUserId();
            isApply = courseEnrollService.isApply(live.getId(), userId, 2);
            if (isApply == 0) {//未购买
                Integer vip = vipService.isVip(openUserAuth.getUserId());
                //判断是否是VIP
                if (vip > 0) {
                    Integer vipFree = live.getIsVipFree();
                    if (vipFree.equals(0)) {
                        isApply = 1;
                    }
                }
            } else {
                isApply = 1;
            }
            // 用户是否收藏（0未收藏1已收藏）
            isCollecon = colleconService.isCollecon(live.getId(), userId, 2, 1);
            url = Md5Sign.getUrl(userId, live.getChannelId());
        }

        map.put("isCollecon", isCollecon);// 用户是否收藏（0未收藏1已收藏）
        live.setLiveUrl(url);
        SysLecturer lecturer = lecturerService.getById(live.getLecturerId());
        if (ObjectUtils.isEmpty(lecturer)) {
            lecturer = new SysLecturer();
        }
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        BigDecimal price = live.getRegFee();
        BigDecimal iosPrice = price.multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP);
        if (price.compareTo(new BigDecimal("0")) == 0) {
            isApply = 1;
        }
        map.put("isApply", isApply);// 用户是否已经报名（0未报名1已报名）
        live.setIosPrice(iosPrice);
        map.put("lecturer", lecturer);// 讲师
        map.put("list", live);// 直播详情
        return ResultBody.success(map);
    }


    /**
     * 搜索页面
     */
    @RequestMapping(value = "/searchPage")
    public ResultBody searchPage() {
        EntityMap map = new EntityMap();
        List<EntityMap> list = keywordService.selectList();
        map.put("list", list);
        return ResultBody.success(map);
    }

    /**
     * 首页搜索
     */
    @RequestMapping(value = "/search")
    public ResultBody search(String keyWord, PagerInfo pagerInfo) {
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        EntityMap map = new EntityMap();
        if (ObjectUtils.isEmpty(keyWord)) {
            map.put("list", new ArrayList<>());
            map.put("lecturers", new ArrayList<>());
            return ResultBody.success(map);
        }
        List<EntityMap> list = courseService.searchCourse(iosRatio, keyWord, pagerInfo);
        map.put("list", list);
        List<EntityMap> lecturers = lecturerService.searchLecturer(keyWord, pagerInfo);
        map.put("lecturers", lecturers);
        map.put("isVip", 0);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Integer vip = vipService.isVip(openUserAuth.getUserId());
            map.put("isVip", vip);
        }
        return ResultBody.success(map);
    }


    /**
     * 首页搜索线下课程
     */
    @RequestMapping(value = "/searchCourse")
    public ResultBody searchCourse(String keyWord, PagerInfo pagerInfo) {
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        EntityMap map = new EntityMap();
        PqGrid pqGrid= offCourseService.searchpageCourse(iosRatio, keyWord, pagerInfo);
//        map.put("courselist", list);
//        List<EntityMap> lecturers = lecturerService.searchLecturer(keyWord, pagerInfo);
//        map.put("lecturers", lecturers);
////        map.put("isVip", 0);
//        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
//        if (ObjectUtils.isNotEmpty(openUserAuth)) {
//            Integer vip = vipService.isVip(openUserAuth.getUserId());
//            map.put("isVip", vip);
//        }
        return ResultBody.success(pqGrid);
    }

    /**
     * 课程详情
     */
    @RequestMapping(value = "/courseDetail")
    public ResultBody courseDetail(Long courseId, PagerInfo pagerInfo) {
        ApiAssert.notNull("参数不能为空", courseId);
        Long accountInfoId = null;
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            accountInfoId = openUserAuth.getUserId();
        }
        EntityMap detail = new EntityMap();
        putAliyun(detail);
        SysCourse course = courseService.getById(courseId);// 课程
        if (ObjectUtil.isNotNull(course.getRecordNum())) {
            course.setRecordNum(course.getRecordNum() + 1);
        } else {
            course.setRecordNum(1);
        }
        courseService.saveOrUpdate(course);
        SysLecturer lecturer = lecturerService.getById(course.getLecturerId());// 讲师
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        // 详情
        EntityMap courseDetail = new EntityMap();
        courseDetail.put("courseName", course.getCourseTitle());// 课程名称
        courseDetail.put("detail", course.getCourseContent());// 简介
        List<EntityMap> recommends = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(lecturer)) {
            courseDetail.put("lecturerImg", lecturer.getLecturerImg());// 讲师头像
            courseDetail.put("lecturerName", lecturer.getLecturerName());// 讲师名称
            courseDetail.put("lecturerContent", lecturer.getContent());// 讲师简介
            recommends = courseService.selectByLecturer(iosRatio, String.valueOf(lecturer.getId()), new PagerInfo());
        } else {
            courseDetail.put("lecturerImg", "");// 讲师头像
            courseDetail.put("lecturerName", "");// 讲师名称
            courseDetail.put("lecturerContent", "");// 讲师简介
        }
        detail.put("recommends", recommends);
        courseDetail.put("coursePrice", course.getCoursePrice());
        courseDetail.put("courseId", course.getId());
        courseDetail.put("courseImage", course.getCourseImage());
        BigDecimal price = course.getCoursePrice();
        courseDetail.put("iosPrice", price.multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
        // 推荐课程
        detail.put("courseUrl", course.getCourseUrl());// 课程视频
        detail.put("courseDetail", courseDetail);// 课程详情
        // 目录
        List<Map<String, Object>> oneList = catalogService.selectOne(courseId);
        if (ObjectUtils.isNotEmpty(oneList)) {
            Integer one = 1;
            for (Map<String, Object> cl : oneList) {
                List<EntityMap> twoList = catalogService.selectTwo2(cl.get("id").toString(),
                    course.getCourseTitle(), course.getCourseImage());
                Integer two = 1;
                /*for(EntityMap twoCatalog : twoList){
                    twoCatalog.put("cataLogNo", one+"."+two);
                    ++two;
                }*/
                cl.put("twoList", twoList);
                ++one;
            }
        }
        detail.put("catalog", oneList);
        // 评论
        List<EntityMap> replysOne = commentService.selectByCourse(courseId.toString(), pagerInfo, 1);// 课程的一级评论
        for (EntityMap one : replysOne) {
            //one.put("createDate", DateUtil.getDateTime(one.get("createDate"), DateUtil.MM月dd日HHmm));
            one.put("createDate", one.get("createDate"));
            // 查询用户是否点赞
            one.put("isThumbs", 0);
            if (ObjectUtils.isNotEmpty(accountInfoId)) {
                Long id = one.get("id");
                Integer isThumbs = colleconService.isCollecon(id, accountInfoId, 3, 2);
                one.put("isThumbs", isThumbs);
            }
            List<EntityMap> replysTwo = courseCommentService.selectByCourse2(one.get("id").toString(),new PagerInfo(), 2, String.valueOf(accountInfoId));// 一级评论的二级级评论
            for (EntityMap two : replysTwo) {
                //two.put("createDate", DateUtil.getDateTime(two.get("createTime"), DateUtil.MM月dd日HHmm));
                two.put("createDate", two.get("createTime"));
            }
            one.put("replysTwo", replysTwo);
            Integer thumbs = colleconService.countByTarget(one.get("id").toString(), 2);
            one.put("thumbs", thumbs);
        }
        detail.put("replys", replysOne);
        detail.put("userId", "");
        // 是否收藏/购买
        if (ObjectUtils.isEmpty(accountInfoId)) {// 未登录用户关注/购买为否
            detail.put("isCollecon", 0);
            detail.put("isBuy", 0);
            return ResultBody.success(detail);
        }
        detail.put("userId", accountInfoId);
        BigDecimal coursePrice = course.getCoursePrice();
        Integer isBuy;
        if (coursePrice.compareTo(BigDecimal.ZERO) <= 0) {
            //免費课程
            isBuy = 1;
        } else {
            isBuy = courseapplyService.isApply(courseId, accountInfoId, 1);// 是否购买
            if (isBuy == 0) {
                Integer vip = vipService.isVip(openUserAuth.getUserId());
                //判断是否是VIP
                if (vip > 0) {
                    Integer vipFree = course.getIsVipFree();
                    if (vipFree.equals(0)) {
                        isBuy = 1;
                    }
                }
            } else {
                isBuy = 1;
            }

        }
        detail.put("isBuy", isBuy);//是否购买
        Integer isCollecon = colleconService.isCollecon(courseId, accountInfoId, 1, 1);// 是否收藏
        detail.put("isCollecon", 0);
        if (isCollecon > 0) {
            detail.put("isCollecon", 1);
        }
        // 添加观看记录
        SysHistory history = historyService.findByUser(accountInfoId.toString(), courseId.toString());
        if (ObjectUtils.isNotEmpty(history)) {
            history.setCreateTime(new DateTime());
            historyService.saveOrUpdate(history);
        } else {
            history = new SysHistory();
            history.setUserId(accountInfoId.toString());
            history.setCourseId(courseId.toString());
            historyService.save(history);
        }
        return ResultBody.success(detail);
    }

    /**
     * 通过videoId查询课程
     */
    @RequestMapping(value = "/findByVideo")
    public ResultBody findByVideo(String videoId) {
        ApiAssert.notNull("videoId不能为空", videoId);
        EntityMap map = new EntityMap();
        SysCataLog catalog = catalogService.findByVideoId(videoId);
        if (ObjectUtils.isEmpty(catalog)) {
            return ResultBody.failed("未查询到对应目录");
        }
        SysCourse course = courseService.getById(catalog.getCourseId());
        if (ObjectUtils.isEmpty(course)) {
            course = new SysCourse();
        }
        putAliyun(map);
        map.put("course", course);
        map.put("catalogId", catalog.getId());
        return ResultBody.success(map);
    }

    public void putAliyun(EntityMap map) {
        map.put("akid", configservice.getByName("AccessKeyId").getConfigVal());
        map.put("akSecret", configservice.getByName("AccessKeySecret").getConfigVal());
        map.put("token", configservice.getByName("SecurityToken").getConfigVal());
    }


    /**
     * vip页面
     */
    @PostMapping(value = "/vipPage")
    public ResultBody vipPage() {
        EntityMap map = new EntityMap();
        SysVipType vipType = vipTypeService.findByCode("VIP");
        List<SysVipPrice> list = vipPriceService.selectByType(vipType.getId());
        map.put("list", list);

        return ResultBody.success(map);
    }

    /**
     * vip页面
     */
    @PostMapping(value = "/vipPagethird")
    public ResultBody vipPagethird() {
        EntityMap map = new EntityMap();
        SysVipType vipType = vipTypeService.findByCode("VIP");
        List<SysVipPrice> list = vipPriceService.selectByType(vipType.getId());
        map.put("list", list);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Integer vip = vipService.isVip(openUserAuth.getUserId());
            map.put("isVip", vip);
            if(vip!=0){
                //开通vip用户 查询有效期
                EntityMap entityMap= vipService.getVipByUser(openUserAuth.getUserId());
                map.put("expiryDate", entityMap.get("expiryDate"));
            }
        }
        SysUser user=userService.getById(openUserAuth.getUserId());
        map.put("mobile", user.getMobile());
        map.put("avatar", user.getAvatar());
        return ResultBody.success(map);
    }



    /**
     * 讲师课程列表
     */
    @PostMapping(value = "/lecturerCourse")
    public ResultBody lecturerCourse(String lecturerId, PagerInfo pagerInfo) {
        ApiAssert.notNull("参数不能为空", lecturerId);
        EntityMap map = new EntityMap();
        SysConfig config = configservice.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        List<EntityMap> list = courseService.selectByLecturer(iosRatio, lecturerId, pagerInfo);
        map.put("isVip", 0);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            Integer vip = vipService.isVip(openUserAuth.getUserId());
            map.put("isVip", vip);
        }
        if (list.size() < 1) {
            map.put("lists", new ArrayList());
            return ResultBody.success(map);
        }
        map.put("lists", list);
        return ResultBody.success(map);
    }

    /**
     * 广告图
     */
    @PostMapping(value = "/advertising")
    public ResultBody advertising(PagerInfo pagerInfo) {
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        cq.select("id,sliderImg originalImg,sliderImg condenseImg,isShow,sortOrder");
        cq.eq("sliderType", CommonConstants.SLIDER_START);
        PqGrid pqGrid = sliderService.pageList(cq);
        EntityMap map = new EntityMap();
        map.put("list", pqGrid.getRows());
        return ResultBody.success(map);
    }

    /**
     * 评论详情
     */
    @PostMapping(value = "/commentDetail")
    public ResultBody commentDetail(String commentId, PagerInfo pagerInfo) {
        ApiAssert.notNull("内容不能为空", commentId);
        EntityMap map = new EntityMap();
        String accountId = null;
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        if (ObjectUtils.isNotEmpty(openUserAuth)) {
            accountId = String.valueOf(openUserAuth.getUserId());
        }
        EntityMap commentDetail = commentService.findByComment(commentId, accountId);
        //commentDetail.put("createDate", DateUtil.getDateTime(commentDetail.get("createTime"), DateUtil.MM月dd日HHmm));
        commentDetail.put("createDate", commentDetail.get("createTime"));
        List<EntityMap> replysTwo = commentService.selectByCourse2(commentId, pagerInfo, 2, accountId);//一级评论的二级级评论
        for (EntityMap two : replysTwo) {
            //two.put("createDate", DateUtil.getDateTime(two.get("createTime"), DateUtil.MM月dd日HHmm));
            two.put("createDate", two.get("createTime"));
        }
        commentDetail.put("replysTwo", replysTwo);
        map.put("commentDetail", commentDetail);
        return ResultBody.success(map);
    }


    /**
     * 支付回调地址 方式二
     */
    @RequestMapping(value = "payBack{orderId}")
    public String payBack(HttpServletRequest request, @PathVariable String orderId) throws IOException {
        Order order = orderService.getById(orderId);
        PayResponse payResponse = service.getPayCallBackResponse(request, order);
        String content = payResponse.getService().payBack(request.getParameterMap(), request.getInputStream()).toMessage();
        return content;
    }

    /**
     * yes
     * vip页面
     */
    @RequestMapping(value = "/vipPageWeb")
    public ResultBody vipPageWeb(HttpServletResponse response) {
        EntityMap map = new EntityMap();
        List<Map<String, Object>> list = vipTypeService.selectAllVip();
        for (Map<String, Object> vip : list) {
            Long id = (Long) vip.get("id");
            List<SysVipconfig> vipconfig = vipconfigService.selectByVip(id);
            vip.put("vipconfig", vipconfig);
        }
        map.put("list", list);
        Integer company = vipService.countVip(1);
        Integer person = vipService.countVip(2);
        map.put("company", company);
        map.put("person", person);
        return ResultBody.success(map);
    }

    /**
     * 报考常见问题
     */
    @GetMapping(value = "/helpexam/{id}")
    public ResultBody helpexam(ModelMap map, @PathVariable Long id) {
        ApiAssert.notNull("参数不能为空", id);
        SysHtml html = htmlService.getById(id);
        return ResultBody.success(html.getHtmlContent());
    }


    /**
     * 常见问题
     */
    @PostMapping(value = "/help_list")
    public ResultBody help_list() {
        CriteriaQuery q = new CriteriaQuery<SysHtml>();
        List list = htmlService.list(q.select("htmlTitle,id").eq(true, "parentId", "2"));
        return ResultBody.success(list);
    }

    /**
     * 折线图数据
     */
    @GetMapping(value = "/line_data")
    public ResultBody line_data(Long userId) {
        String date = DateUtil.format(DateUtil.beginOfWeek(DateUtil.date()), "YYYY-MM-dd");
        List<EntityMap> entityMaps = examRecordService.totalScore(date, userId);
        DateTime dateTime = DateUtil.beginOfWeek(DateUtil.date());//本周开始日期
        String dateStr = DateUtil.formatDate(dateTime);
        List<EntityMap> newList = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            if (i > 0) {
                dateStr = DateUtil.formatDate(DateUtil.offsetDay(dateTime, i));
            }
            boolean tag = true;
            for (EntityMap em : entityMaps) {
                if (dateStr.equals(em.get("initDay").toString())) {
                    tag = false;
                    newList.add(em);
                }
            }
            if (tag) {//没有符合的
                EntityMap data = new EntityMap();
                data.put("score", 0);
                data.put("initDay", dateStr);
                data.put("days", DateUtil.format(DateUtil.offsetDay(dateTime, i), "MM.dd"));
                newList.add(data);
            }
        }
        return ResultBody.success(newList);
    }


    /**
     * 折线图数据
     */
    @GetMapping(value = "/line_data2")
    public ResultBody line_data2(Long userId) {
        String date = DateUtil.format(DateUtil.beginOfWeek(DateUtil.date()), "YYYY-MM-dd");
        List<EntityMap> entityMaps = examRecordService.totalScore(date, userId);
        DateTime dateTime = DateUtil.beginOfWeek(DateUtil.date());//本周开始日期
        String dateStr = DateUtil.formatDate(dateTime);
        List<EntityMap> newList = new ArrayList<>();

        List<String> datas = new ArrayList<>();
        List<Integer> scores = new ArrayList<>();
        EntityMap map = new EntityMap();
        for (int i = 0; i < 7; i++) {
            if (i > 0) {
                dateStr = DateUtil.formatDate(DateUtil.offsetDay(dateTime, i));
            }
            boolean tag = true;
            for (EntityMap em : entityMaps) {
                if (dateStr.equals(em.get("initDay").toString())) {
                    tag = false;
                    datas.add(em.get("days"));
                    scores.add(em.get("score"));
                    newList.add(em);
                }
            }
            if (tag) {//没有符合的

                datas.add(DateUtil.format(DateUtil.offsetDay(dateTime, i), "MM.dd"));
                scores.add(0);

            }
         }
        map.put("datas", datas);
        map.put("scores", scores);
        return ResultBody.success(map);
    }


    /**
     * 获取二维码图像 二维码支付
     */
    @RequestMapping(value = "toQrPay", produces = "image/jpeg;charset=UTF-8")
    public byte[] toWxQrPay(HttpServletRequest request, String transactionType) throws IOException {
        String payCode = request.getParameter("payCode");
        request.setAttribute("payCode", payCode);
        String orderId = request.getParameter("orderId");
        orderService.editOrder(UUID.randomUUID().toString().replace("-", ""), orderId, payCode);// 更新订单的第三方流水号
        Order order = orderService.getById(orderId);
        // 获取对应的支付账户操作工具（可根据账户id）
        PayResponse payResponse = service.getPayResponsePC(request);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BigDecimal price = order.getOrderAmount();          //正式价格
//        BigDecimal price = new BigDecimal("0.05");        //测试价格  统一0.05
        PayOrder payOrder = new PayOrder(order.getOrderTitle(), order.getOrderBody(), null == price ? new BigDecimal(0.01) : price, order.getOutTradeNo() + "", PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
        payOrder.setAddition(OrderTypeEnum.getName(order.getOrderEntity().name()));
        ImageIO.write(payResponse.getService().genQrPay(payOrder), "JPEG", baos);
        return baos.toByteArray();
    }


    /**
     * 银联支付回调
     */
    @RequestMapping("unionpay_back")
    public String unionpayBack(HttpServletResponse response, String content, String signature) {
        try {
            Map<String, String> map = XmlUtileXM.xmlToMap(content, "GBK");
            if (ObjectUtils.isNotEmpty(map.get("RTNFLG"))) {
                if (map.get("RTNFLG").equals("M") && ObjectUtils.isNotEmpty(map.get("REFORD"))) {//订单处理完成且订单号不为空
                    ZSHttpRequest request = new ZSHttpRequest();
                    String outTradeNo = map.get("REFORD");
                    //查询订单状态
                    String data = request.findOrder(outTradeNo);
                    String result = request.sendRequest(data);
                    Map<String, String> reMap = XmlUtileXM.xmlToMap(result, "GBK");
                    //订单支付成功
                    if (reMap.get("ORDSTA").equals("FIN") && reMap.get("ORDSTS").equals("S")) {
                        //处理订单逻辑
                        balanceService.unionpay_back(outTradeNo);
                        return "<?xml version='1.0' encoding='ISO8859-1'?><DATA><RESPONSE>"
                            + "<STSCOD>00000000</STSCOD><STSMSG></STSMSG></RESPONSE></DATA>";
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        System.out.println("银行回调内容：" + content);
        System.out.println("银行回调签名：" + signature);
        return "<?xml version='1.0' encoding='ISO8859-1'?><DATA><RESPONSE><STSCOD>ERR00002</STSCOD><STSMSG>无效订单号</STSMSG></RESPONSE></DATA>";
    }

    /**
     * 招商银行查询订单是否支付成功
     */
    @RequestMapping("unionpay_check")
    public ResultBody unionpayCheck(HttpServletResponse response, String outTradeNo) {
        ZSHttpRequest request = new ZSHttpRequest();
        //查询订单状态
        String data = request.findOrder(outTradeNo);
        String result = request.sendRequest(data);
        Map<String, String> reMap;
        try {
            reMap = XmlUtileXM.xmlToMap(result, "GBK");
            //订单支付成功
            if (reMap.get("ORDSTA").equals("FIN") && reMap.get("ORDSTS").equals("S")) {
                //处理订单逻辑
                balanceService.unionpay_back(outTradeNo);
                return ResultBody.ok("订单支付成功，已添加企业VIP");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return ResultBody.failed("订单等待中");
    }

    /**
     * 课程详情
     */
    @RequestMapping(value = "/coursestudyDetail")
    public ResultBody coursestudyDetail(Long courseId, PagerInfo pagerInfo,Long userCertifiId) {
        ApiAssert.notNull("参数不能为空", courseId);
        EntityMap detail = new EntityMap();
        putAliyun(detail);
        SysCourse course = courseService.getById(courseId);// 课程
        //课程浏览量
        if (ObjectUtil.isNotNull(course.getRecordNum())) {
            course.setRecordNum(course.getRecordNum() + 1);
        } else {
            course.setRecordNum(1);
        }
        courseService.saveOrUpdate(course);
        detail.put("recordNum",course.getRecordNum());
        SysLecturer lecturer = lecturerService.getById(course.getLecturerId());// 讲师
        // 详情
        EntityMap courseDetail = new EntityMap();
        courseDetail.put("isVipFree",course.getIsVipFree());    //Vip免费
        courseDetail.put("isFree",course.getIsFree());          //课程免费
        courseDetail.put("courseName", course.getCourseTitle());// 课程名称
        courseDetail.put("detail", course.getCourseContent());// 简介
        List<EntityMap> recommends = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(lecturer)) {
            courseDetail.put("lecturerImg", lecturer.getLecturerImg());// 讲师头像
            courseDetail.put("lecturerName", lecturer.getLecturerName());// 讲师名称
            courseDetail.put("lecturerContent", lecturer.getContent());// 讲师简介
            SysConfig config = configservice.getByName("iosRatio");
            BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
            recommends = courseService.selectByLecturer(iosRatio, String.valueOf(lecturer.getId()), new PagerInfo());
        } else {
            courseDetail.put("lecturerImg", "");// 讲师头像
            courseDetail.put("lecturerName", "");// 讲师名称
            courseDetail.put("lecturerContent", "");// 讲师简介
        }
        detail.put("recommends", recommends);
        courseDetail.put("coursePrice", course.getCoursePrice());
        courseDetail.put("courseId", course.getId());
        courseDetail.put("courseImage", course.getCourseImage());
        courseDetail.put("iosPrice", course.getIosPrice());
        detail.put("courseUrl", course.getCourseUrl());// 课程视频
        detail.put("courseDetail", courseDetail);// 课程详情
        // 目录
        List<Map<String, Object>> oneList = catalogService.selectOne(courseId);
        if (ObjectUtils.isNotEmpty(oneList)) {
            Integer one = 1;
            for (Map<String, Object> cl : oneList) {
                List<EntityMap> twoList = catalogService.selectTwo2(cl.get("id").toString(),
                    course.getCourseTitle(), course.getCourseImage());
                for(EntityMap courseMap:twoList){
                    //判断学习周期内的学习记录
                    EntityMap userCert= sysUsercertificateService.getUsercertifie(userCertifiId);
                    String validity=userCert.get("validity");
                    Date timetimp = DateUtil.parse(validity,"yyyy-MM-dd");
                    DateTime dateTime = DateUtil.beginOfYear(timetimp);
                    Calendar startcalendar = dateTime.toCalendar();
                    Calendar endcalendar = dateTime.toCalendar();
//                    startcalendar.add(Calendar.YEAR, -1);
//                    endcalendar.add(Calendar.YEAR, -1);
                    endcalendar.add(Calendar.MONTH, 11);
                    endcalendar.add(Calendar.DATE, 30);
                    String startTime = DateUtils.formatDate(startcalendar.getTime(), "yyyy-MM-dd");
                    String endTime = DateUtils.formatDate(endcalendar.getTime(), "yyyy-MM-dd");
                    List<EntityMap> mapList= sysCertifistudyrecordService.getuserStudyRecord(Long.parseLong(courseMap.get("courseId").toString()), Long.parseLong(courseMap.get("id").toString()),userCertifiId,startTime,endTime);
                    if(mapList.size()>0){
                        courseMap.put("courseStudyStatus",1);
                    }else{
                        courseMap.put("courseStudyStatus",0);
                    }
                }
                Integer two = 1;
                cl.put("twoList", twoList);
                ++one;
            }
        }
        detail.put("catalog", oneList);
        return ResultBody.success(detail);
    }

    /**
     * 视频观看完成记录用户学习计划
     */
    @PostMapping(value = "/addstudyDetail")
    public ResultBody sendPlan(Long catalogId,Long usercertfiId,Long courseId) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        SysUser user = userService.getById(openUserAuth.getUserId());
        SysCataLog catalog = catalogService.getById(catalogId);
        ApiAssert.notNull("视频不存在", catalog);
        //课程章节数
        int cataNum= sysCataLogService.countByCourseId(courseId);
        EntityMap userCert= sysUsercertificateService.getUsercertifie(usercertfiId);
        SysStudyconfig sysStudyconfig= sysStudyconfigService.getByStudyConfig(userCert.get("certificateId"));
        String validity=userCert.get("validity");
        Date timetimp = DateUtil.parse(validity,"yyyy-MM-dd");
        DateTime dateTime = DateUtil.beginOfYear(timetimp);
        Calendar startcalendar = dateTime.toCalendar();
        Calendar endcalendar = dateTime.toCalendar();
        Calendar certcalendar = dateTime.toCalendar();
        certcalendar.add(Calendar.YEAR, 1);
//        startcalendar.add(Calendar.YEAR, -1);
//        endcalendar.add(Calendar.YEAR, -1);
        endcalendar.add(Calendar.MONTH, 11);
        endcalendar.add(Calendar.DATE, 30);
        String startTime = DateUtils.formatDate(startcalendar.getTime(), "yyyy-MM-dd");
        String endTime = DateUtils.formatDate(endcalendar.getTime(), "yyyy-MM-dd");
        String newValidity = DateUtils.formatDate(certcalendar.getTime(), "yyyy-MM-dd");
        //判断该课程是否在学习周期学过
        List<EntityMap> mapList= sysCertifistudyrecordService.getuserStudyRecord(courseId,catalogId,usercertfiId,startTime,endTime);
        if(ObjectUtils.isEmpty(mapList)) {
            SysCertifistudyrecord sysCertifistudyrecord = new SysCertifistudyrecord();
            sysCertifistudyrecord.setCatalogId(catalogId);
            sysCertifistudyrecord.setCourserId(courseId);
            sysCertifistudyrecord.setSysuserCertifiId(usercertfiId);
            boolean a = sysCertifistudyrecordService.save(sysCertifistudyrecord);
        }
        //判断学习周期内学了多少章节
        List<EntityMap> courseList= sysCertifistudyrecordService.getuserStudyRecord(courseId,null,usercertfiId,startTime,endTime);
        //判断是否为最后一章节
        if(cataNum==courseList.size()){
            //判断继续教育相关课程是否在学习期内学完
            List<EntityMap> courseListmap=sysPeriodrecordService.getPeriodrecord(openUserAuth.getUserId(),courseId,usercertfiId,startTime,endTime);
            //重复学习不计入学时
            if(ObjectUtils.isEmpty(courseListmap)){
                EntityMap entityMap=sysContinuecourseService.getConfugCourse(courseId,userCert.get("certificateId"));
                SysPeriodrecord sysPeriodrecord=new SysPeriodrecord();
                sysPeriodrecord.setPeriod(entityMap.get("period"));
                sysPeriodrecord.setPeriodType(1);
                sysPeriodrecord.setCourseId(courseId);
                sysPeriodrecord.setUsercertificateId(usercertfiId);
                sysPeriodrecord.setUserId(openUserAuth.getUserId());
                sysPeriodrecordService.save(sysPeriodrecord);//course学完
            }
            List<EntityMap> coursemap=sysPeriodrecordService.getPeriodrecord(openUserAuth.getUserId(),null,usercertfiId,startTime,endTime);
            List<EntityMap> configList= sysContinuecourseService.getStudyConfugCourse(userCert.get("certificateId"));
            //学完更新继续教育课程学时
            int sumPeriod=0;
            int allPeriod=0;
            SysUsercertificate b=sysUsercertificateService.getById(usercertfiId);
            if(coursemap.size()==configList.size()){
                for(EntityMap map:configList){
                    int period=map.get("period");
                    sumPeriod+=period;
                }
                allPeriod=sumPeriod;
                //继续教育周期范围内活动审核通过学时
                int activityPeiod=0;
                List<EntityMap> mapactivity= sysActivityrecordService.getActivityList(usercertfiId,startTime,endTime);
                if(ObjectUtils.isNotEmpty(mapactivity)){
                    for (EntityMap activity:mapactivity ) {
                        int period=activity.get("period");
                        activityPeiod+=period;
                    }
                }
                allPeriod+=activityPeiod;
                if(allPeriod>= sysStudyconfig.getTagetPeriod()){
                    if(ObjectUtils.isNotEmpty(b.getSumperiod())){
                        b.setSumperiod(b.getSumperiod()+sumPeriod);
                    }else{
                        b.setSumperiod(sumPeriod);
                    }
                    b.setIsFull(1);
                    b.setValidity(newValidity);
                    if(ObjectUtils.isNotEmpty(b.getUserperiod())){
                        b.setUserperiod(b.getUserperiod()+sumPeriod);
                    }else{
                        b.setUserperiod(sumPeriod);
                    }
                    boolean a=sysUsercertificateService.saveOrUpdate(b);
                    if(a){
                        return ResultBody.ok("继续教育相关课程已完成，该证书有效期延期一年");
                    }
                }else{
                    //课程所得学时
                    if(ObjectUtils.isEmpty(courseListmap)){
                        if(ObjectUtils.isNotEmpty(b.getUserperiod())){
                            b.setUserperiod(b.getUserperiod()+sumPeriod);
                        }else{
                            b.setUserperiod(sumPeriod);
                        }
                        boolean a=sysUsercertificateService.saveOrUpdate(b);
                    }
                }
            }else{
                for(EntityMap map:coursemap){
                    int period=map.get("period");
                    sumPeriod+=period;
                }
                b.setUserperiod(sumPeriod);
                boolean a=sysUsercertificateService.saveOrUpdate(b);
            }
        }
        return ResultBody.ok("添加成功");
    }

    /**
     * 获取点播信息
     */
    @RequestMapping(value = "/vod/info")
    public ResultBody getVodInfo() {
        List<SysConfig> list = configservice.getVodInfo();
        EntityMap map = new EntityMap();
        if(list.size() > 0){
            for (SysConfig config : list){
                map.put(config.getConfigName(), config.getConfigVal());
            }
        }
        return ResultBody.success(map);
    }

    /**
     * 获取发票信息
     */
    @RequestMapping(value = "/nuo/info")
    public ResultBody getNuoInfo() {
        SysConfig config = configservice.getNuoInfo();
        EntityMap map = new EntityMap();
        map.put(config.getConfigName(), config.getConfigVal());
        return ResultBody.success(map);
    }

    public static void main(String[] t) {
        String date = DateUtil.format(DateUtil.beginOfWeek(DateUtil.date()), "YYYY-MM-dd");
        System.out.println(date);
    }


}
